package com.rush.yuaiagent.agent.model;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.ToolResponseMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.model.tool.ToolCallingManager;
import org.springframework.ai.model.tool.ToolExecutionResult;
import org.springframework.ai.tool.ToolCallback;

import java.util.List;
import java.util.stream.Collectors;
/**
 * 处理工具调用的基础代理类，具体实现了 think 和 act 方法，可以用作创建实例的父类
 */
@EqualsAndHashCode(callSuper = true)
@Data
@Slf4j
public class ToolCallAgent extends ReActAgent {

    // 可用的工具
    private final ToolCallback[] availableTools;

    // 保存了工具调用信息的响应
    private ChatResponse toolCallChatResponse;

    // 工具调用管理者
    private final ToolCallingManager toolCallingManager;

    // 禁用内置的工具调用机制，自己维护上下文
    private final ChatOptions chatOptions;
    
    // 存储最新的思考和行动详情，用于SSE输出
    private String lastThinkingDetail = "";
    private String lastActionDetail = "";

    public ToolCallAgent(ToolCallback[] availableTools) {
        super();
        this.availableTools = availableTools;
        this.toolCallingManager = ToolCallingManager.builder().build();
        // 禁用 Spring AI 内置的工具调用机制，自己维护选项和消息上下文
        this.chatOptions = DashScopeChatOptions.builder()
                .withProxyToolCalls(true)
                .build();
    }
    /**
     * 处理当前状态并决定下一步行动
     *
     * @return 是否需要执行行动
     */
    @Override
    public boolean think() {
        if (getNextPrompt() != null && !getNextPrompt().isEmpty()) {
            UserMessage userMessage = new UserMessage(getNextPrompt());
            getMessageList().add(userMessage);
        }
        List<Message> messageList = getMessageList();
        Prompt prompt = new Prompt(messageList, chatOptions);
        try {
            // 获取带工具选项的响应
            ChatResponse chatResponse = getChatClient().prompt(prompt)
                    .system(getSystemPrompt())
                    .tools(availableTools)
                    .call()
                    .chatResponse();
            // 记录响应，用于 Act
            this.toolCallChatResponse = chatResponse;
            AssistantMessage assistantMessage = chatResponse.getResult().getOutput();
            // 输出提示信息
            String result = assistantMessage.getText();
            List<AssistantMessage.ToolCall> toolCallList = assistantMessage.getToolCalls();
            
            // 构建详细的思考描述
            StringBuilder thinkingDetail = new StringBuilder();
            if (result != null && !result.trim().isEmpty()) {
                thinkingDetail.append("💭 AI思考: ").append(result).append("\n");
            }
            thinkingDetail.append("🔧 工具选择: ").append(toolCallList.size()).append(" 个工具");
            
            if (!toolCallList.isEmpty()) {
                thinkingDetail.append("\n📋 计划执行的工具:\n");
                String toolCallInfo = toolCallList.stream()
                        .map(toolCall -> String.format("   • %s (参数: %s)",
                                toolCall.name(),
                                toolCall.arguments())
                        )
                        .collect(Collectors.joining("\n"));
                thinkingDetail.append(toolCallInfo);
            } else {
                thinkingDetail.append(" - 无需调用工具");
            }
            
            // 存储思考详情
            this.lastThinkingDetail = thinkingDetail.toString();
            
            log.info(getName() + "的思考: " + result);
            log.info(getName() + "选择了 " + toolCallList.size() + " 个工具来使用");
            if (!toolCallList.isEmpty()) {
                log.info("工具详情:\n" + toolCallList.stream()
                        .map(toolCall -> String.format("工具名称：%s，参数：%s",
                                toolCall.name(),
                                toolCall.arguments()))
                        .collect(Collectors.joining("\n")));
            }
            
            if (toolCallList.isEmpty()) {
                // 只有不调用工具时，才记录助手消息
                getMessageList().add(assistantMessage);
                return false;
            } else {
                // 需要调用工具时，无需记录助手消息，因为调用工具时会自动记录
                return true;
            }
        } catch (Exception e) {
            this.lastThinkingDetail = "❌ 思考过程出现错误: " + e.getMessage();
            log.error(getName() + "的思考过程遇到了问题: " + e.getMessage());
            getMessageList().add(
                    new AssistantMessage("处理时遇到错误: " + e.getMessage()));
            return false;
        }
    }
    /**
     * 执行工具调用并处理结果
     *
     * @return 执行结果
     */
    @Override
    public String act() {
        if (!toolCallChatResponse.hasToolCalls()) {
            this.lastActionDetail = "⏭️ 跳过行动 - 没有工具需要调用";
            return "没有工具调用";
        }
        
        try {
            // 调用工具
            Prompt prompt = new Prompt(getMessageList(), chatOptions);
            ToolExecutionResult toolExecutionResult = toolCallingManager.executeToolCalls(prompt, toolCallChatResponse);
            // 记录消息上下文，conversationHistory 已经包含了助手消息和工具调用返回的结果
            setMessageList(toolExecutionResult.conversationHistory());
            // 当前工具调用的结果
            ToolResponseMessage toolResponseMessage = (ToolResponseMessage) CollUtil.getLast(toolExecutionResult.conversationHistory());
            
            // 构建详细的行动描述
            StringBuilder actionDetail = new StringBuilder();
            actionDetail.append("🚀 开始执行工具调用...\n");
            
            var responses = toolResponseMessage.getResponses();
            for (int i = 0; i < responses.size(); i++) {
                var response = responses.get(i);
                actionDetail.append(String.format("📱 工具 %d: %s\n", i + 1, response.name()));
                actionDetail.append(String.format("   状态: ✅ 执行成功\n"));
                
                // 限制响应数据的显示长度，避免过长
                String responseData = response.responseData();
                if (responseData.length() > 200) {
                    responseData = responseData.substring(0, 200) + "...";
                }
                actionDetail.append(String.format("   结果: %s\n", responseData));
            }
            
            // 判断是否调用了终止工具
            boolean terminateToolCalled = responses.stream()
                    .anyMatch(response -> "doTerminate".equals(response.name()));
            if (terminateToolCalled) {
                actionDetail.append("🔚 检测到终止工具调用，任务即将结束");
                setState(AgentState.FINISHED);
            }
            
            // 存储行动详情
            this.lastActionDetail = actionDetail.toString();
            
            String results = responses.stream()
                    .map(response -> "工具 " + response.name() + " 完成了它的任务！结果: " + response.responseData())
                    .collect(Collectors.joining("\n"));
            
            log.info(results);
            return results;
            
        } catch (Exception e) {
            this.lastActionDetail = "❌ 执行工具时出现错误: " + e.getMessage();
            log.error("执行工具时出现错误", e);
            return "执行工具时出现错误: " + e.getMessage();
        }
    }

}
